package cate.game.role.history;

import cate.common.table.activity.exorcism.row.ExorcismGhostRow;
import cate.common.table.d.*;
import cate.common.table.item.equip.row.EquipBaseRow;
import cate.common.table.item.furniture.row.FurnitureItemBaseRow;
import cate.common.table.item.hero.row.HeroTalentRow;
import cate.common.table.item.rune.row.RuneBaseRow;
import cate.game.activity.crossrank.SingleCrossRankActivityHandler;
import cate.game.activity.rank.SingleRankActivityHandler;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.bag.equip.Equip;
import cate.game.role.bag.furniture.Furniture;
import cate.game.role.bag.gem.Gem;
import cate.game.role.bag.hero.Hero;
import cate.game.role.bag.newtalent.TalentItem;
import cate.game.role.bag.rune.Rune;
import cate.game.role.fight.HeroGrid;
import cate.game.role.fight.Position;
import cate.game.role.res.leader.hallows.Hallow;
import cate.game.role.system.RoleSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;

public class HistoryAction {

    private static Logger logger = LoggerFactory.getLogger(HistoryAction.class);

    private RoleHistory parent;

    public HistoryAction(RoleHistory parent) {
        this.parent = parent;
    }

    /**
     * vip等级
     *
     * @param vip
     */
    public void vipLevel(int vip) {
        doRecord(GDHistory.Event.VIP_LEVEL, GDHistory.TID_NULL, vip, false);
    }

    public void vipGetCreateDay(int vip, int createDay) {
        doRecord(GDHistory.Event.VIP_GET_CREATEDAY, vip, createDay, false);
    }

    public void playTimesBuy(int funcId) {
        if (funcId == GDFunc.GuildFunc.BOSS) {
            doRecord(GDHistory.Event.GUILD_BOSS_BUY_TIMES, funcId, 1, true);
        }
    }

    public void costResValue(long num, int type) {
        doRecord(GDHistory.Event.COST_RES_VALUE, type, num, true);
    }

    /**
     * 玩家充值金额,不永久累计
     *
     * @param num 充值的金额
     */
    public void payNum(long num) {
        doRecord(GDHistory.Event.PAY_NUM, GDHistory.TID_NULL, num, true);
    }

    public void payTimes() {
        doRecord(GDHistory.Event.PAY_TIMES, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 精英赛竞猜次数
     */
    public void eliteRaceBet() {
        doRecord(GDHistory.Event.ELITE_RACE_BET, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 精英赛竞猜成功
     */
    public void eliteRaceBetCorrect() {
        doRecord(GDHistory.Event.ELITE_RACE_BET_CORRECT, GDHistory.TID_NULL, 1, true);
    }

    public void eliteRaceJoin() {
        doRecord(GDHistory.Event.ELITE_RACE_JOIN, GDHistory.TID_NULL, 1, true);
    }

    public void pointRaceRankTimes(int rank) {
        doRecord(GDHistory.Event.POINT_RACE_RANK_TIMES, rank, 1, true);
    }

    public void ChampionRaceRankTimes(int rank) {
        doRecord(GDHistory.Event.CHAMPION_RACE_RANK_TIMES, rank, 1, true);
    }

    public void ladderRankTimes(int rank) {
        doRecord(GDHistory.Event.LADDER_RANK_TIMES, rank, 1, true);
    }

    public void eliteRaceRankTimes(int rank) {
        doRecord(GDHistory.Event.ELITE_RACE_RANK_TIMES, rank, 1, true);
    }

    /**
     * 精英赛聊天一次
     */
    public void eliteRaceChatTimes() {
        doRecord(GDHistory.Event.ELITE_RACE_CHAT, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 累计登录天数
     */
    public void loginDays() {
        doRecord(GDHistory.Event.LOGIN_DAYS, GDHistory.TID_NULL, 1, true);
        login();
    }

    /**
     * 冒险等级改变
     */
    public void levelChange(int level) {
        doRecord(GDHistory.Event.ROLE_LEVEL, GDHistory.TID_NULL, level, false);
    }

    public void gradeChange(int grade) {
        doRecord(GDHistory.Event.ROLE_GRADE_UP, GDHistory.TID_NULL, grade, false);
    }

    public void farmGroundLevelNum(int level, int num) {
        doRecord(GDHistory.Event.GROUND_LEVEL_NUM, level, num, false);
    }

    public void farmVipOpen() {
        doRecord(GDHistory.Event.FARM_VIP_OPEN, GDHistory.TID_NULL, 1, true);
    }

    public void farmVipContinue() {
        doRecord(GDHistory.Event.FARM_VIP_CONTINUE, GDHistory.TID_NULL, 1, true);
    }

    public void farmSeedGain(int seedLevel, int seedNum) {
        doRecord(GDHistory.Event.FARM_SEED_GAIN, seedLevel, seedNum, true);
    }

    public void farmPlantTimes(int times) {
        doRecord(GDHistory.Event.FARM_PLANT_TIMES, GDHistory.TID_NULL, times, true);
    }

    /**
     * 友情互赠
     */
    public void friendGiftSentTimes(int times) {
        doRecord(GDHistory.Event.FRIEND_SEND, GDHistory.TID_NULL, times, true);
    }

    /**
     * 友情互赠
     */
    public void friendGiftRecvTimes(int times) {
        doRecord(GDHistory.Event.FRIEND_RECV, GDHistory.TID_NULL, times, true);
    }

    /**
     * 食灵召唤
     * 各个模式召唤统计
     */
    public void heroCall(Byte mode, int times) {
        doRecord(GDHistory.Event.HERO_MODE_CALL, mode, times, true);
        doRecord(GDHistory.Event.HERO_CALL, GDHistory.TID_NULL, times, true);
        if (mode == GDHeroCall.Mode.ADVANCE || mode == GDHeroCall.Mode.FRIEND || mode == GDHeroCall.Mode.NORMAL) {
            doRecord(GDHistory.Event.HERO_CALL_MODE_123, GDHistory.TID_NULL, times, true);
        }
        if (mode == GDHeroCall.Mode.ADVANCE
                || mode == GDHeroCall.Mode.CREAM
                || mode == GDHeroCall.Mode.GOD_EVIL) {
            doRecord(GDHistory.Event.HERO_CALL_MODE_12345, GDHistory.TID_NULL, times, true);

        }
        if (mode == GDHeroCall.Mode.ADVANCE) {
            parent.getRole().getSystem().update(RoleSystem.GmOper.ADVANCE_CALL, times);
        } else if (mode == GDHeroCall.Mode.NATURE) {
            parent.getRole().getSystem().update(RoleSystem.GmOper.GENERAL_WISH, times);
        } else if (mode == GDHeroCall.Mode.CREAM) {
            parent.getRole().getSystem().update(RoleSystem.GmOper.ELITE_CALL, times);
        } else if (mode == GDHeroCall.Mode.GOD_EVIL) {
            parent.getRole().getSystem().update(RoleSystem.GmOper.NIUBI_CALL, times);
        }
    }

    public void heroGodAll(int times) {
        doRecord(GDHistory.Event.HERO_GOD_ALL, GDHistory.TID_NULL, times, true);
    }

    public void heroReplace() {
        doRecord(GDHistory.Event.HERO_REPLACE, GDHistory.TID_NULL, 1, true);
    }

    public void heroCallStar(int star) {
        heroCallStar(star, 1);
    }

    public void dailyActiveValue(long active) {
        doRecord(GDHistory.Event.DAILY_ACTIVE_VALUE, GDHistory.TID_NULL, active, true);
    }

    public void weeklyActiveValue(long active) {
        doRecord(GDHistory.Event.WEEKLY_ACTIVE_VALUE, GDHistory.TID_NULL, active, true);
    }

    public void dailyTaskRewardGet(int times) {
        doRecord(GDHistory.Event.DAILY_TASK_REWARD, GDHistory.TID_NULL, times, true);
    }

    public void weeklyTaskRewardGet(int times) {
        doRecord(GDHistory.Event.WEEKLY_TASK_REWARD, GDHistory.TID_NULL, times, true);
    }

    public void dailyRewardTimes() {
        doRecord(GDHistory.Event.DAILY_REWARD_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void weeklyRewardTimes() {
        doRecord(GDHistory.Event.WEEKLY_REWARD_TIMES, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 获得X次y英雄，只计算新获得的
     *
     * @param heroTid 英雄tid
     * @param num     数量
     */
    public void heroHasTidNum(int heroTid, int num) {
        doRecord(GDHistory.Event.HERO_HAS_TID_NUM, heroTid, num, true);
    }

    public void heroCallStar(int star, int num) {
        doRecord(GDHistory.Event.HERO_CALL_STAR, star, num, true);
    }

    public void heroGodCall(int times) {
        doRecord(GDHistory.Event.HERO_GOD_CALL, GDHistory.TID_NULL, times, true);
    }

    public void heroGodScoreCall(int times) {
        doRecord(GDHistory.Event.HERO_GOD_SCORE_CALL, GDHistory.TID_NULL, times, true);
    }

    public void heroSacrifice(int size) {
        doRecord(GDHistory.Event.HERO_SACRIFICE, GDHistory.TID_NULL, size, true);
    }

    public void speCallWarOrderActive() {
        doRecord(GDHistory.Event.SPE_HERO_WAR_ORDER_ACTIVE, GDHistory.TID_NULL, 1, false);
    }

    public void heroSpeCall(int times) {
        doRecord(GDHistory.Event.SPE_HERO_CALL, GDHistory.TID_NULL, times, true);
    }


    public void endlessCombatNum(int combatNum) {
        doRecord(GDHistory.Event.ENDLESS_COMBAT_NUM, GDHistory.TID_NULL, combatNum, false);
    }

    public void endlessAidTimes() {
        doRecord(GDHistory.Event.ENDLESS_AID_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void endlessDailyReward() {
        doRecord(GDHistory.Event.ENDLESS_DAILY_REWARD, GDHistory.TID_NULL, 1, true);
    }

    public void arenaChallengeTimes() {
        doRecord(GDHistory.Event.ARENA_CHALLENGE_TIMES, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 挑战协会boss
     */
    public void challengeGuildBoss() {
        doRecord(GDHistory.Event.CHALLENGE_GUILD_BOSS, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 协会捐献
     */
    public void guildDonate() {
        doRecord(GDHistory.Event.GUILD_DONATE, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 协会内政任务
     */
    public void guildAffair(int quality) {
        doRecord(GDHistory.Event.GUILD_AFFAIR, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.GUILD_AFFAIR_QUALITY_NUM, quality, 1, true);
    }

    public void guildGeneralSkill(int job, int level) {
        doRecord(GDHistory.Event.GUILD_GENERAL_SKILL, job, level, false);
        doRecord(GDHistory.Event.GUILD_ANY_GENERAL_SKILL, GDHistory.TID_NULL, level, false);
    }

    public void guildPvpSkill(int job, int level) {
        doRecord(GDHistory.Event.GUILD_PVP_SKILL, job, level, false);
        doRecord(GDHistory.Event.GUILD_ANY_PVP_SKILL, GDHistory.TID_NULL, level, false);
    }

    public void formationsLevel(int level) {
        doRecord(GDHistory.Event.FORMATIONS_LEVEL, GDHistory.TID_NULL, level, false);
    }

    public void formationsTimes() {
        doRecord(GDHistory.Event.FORMATIONS_TIMES, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 日常副本
     */
    public void dailyFB(int times) {
        doRecord(GDHistory.Event.DAILYFB, GDHistory.TID_NULL, times, true);
    }

    public void dailyFBWin(int times) {
        doRecord(GDHistory.Event.DAILY_FB_WIN, GDHistory.TID_NULL, times, true);
    }

    /**
     * 主线
     */
    public void adventurePass() {
        doRecord(GDHistory.Event.ADVENTURE, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 领取冒险通关奖励的次数
     *
     * @param id-关卡
     */
    public void adventurePassRewardGet(int id) {
        doRecord(GDHistory.Event.ADVENTURE_PASS_REWARD_GET_TIMES, GDHistory.TID_NULL, 1, true);
        //领取第几关冒险通关奖励（游戏侧边栏单独领取项，非通关直接获得）
        doRecord(GDHistory.Event.ADVENTURE_PASS_REWARD_GET_LEVEL, id, 1, true);
    }

    /**
     * 冒险快速作战次数
     */
    public void adventureFast() {
        doRecord(GDHistory.Event.ADVENTURE_FAST_TIMES, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 挑战主线指定关卡
     *
     * @param num
     */
    public void adventureCombatNum(int num) {
        doRecord(GDHistory.Event.ADVENTURE_COMBAT_NUM, GDHistory.TID_NULL, num, false);
    }

    public void adventureBossKill() {
        doRecord(GDHistory.Event.ADVENTURE_BOSS_KILL, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 积分赛挑战
     */
    public void pointRace() {
        doRecord(GDHistory.Event.POINT_RACE, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 积分赛胜利
     */
    public void pointRaceWin() {
        doRecord(GDHistory.Event.POINT_RACE_WIN, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 积分赛胜利
     */
    public void pointRaceLose() {
        doRecord(GDHistory.Event.POINT_RACE_LOSE, GDHistory.TID_NULL, 1, true);
    }

    public void pointRaceFinalReward() {
        doRecord(GDHistory.Event.POINT_RACE_FINAL_REWARD, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 天梯赛挑战
     */
    public void ladderChallange() {
        doRecord(GDHistory.Event.LADDER_CHALLENGE, GDHistory.TID_NULL, 1, true);
    }

    public void ladderWin() {
        doRecord(GDHistory.Event.LADDER_WIN, GDHistory.TID_NULL, 1, true);
    }

    public void jungleTimes() {
        doRecord(GDHistory.Event.JUNGLE_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void jungleRobTimes() {
        doRecord(GDHistory.Event.JUNGLE_ROB_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void jungleQualityTimes(int quality) {
        if (quality == GDProp.Quality.Q5) {
            doRecord(GDHistory.Event.JUNGLE_QUALITY_TIMES, GDHistory.TID_NULL, 1, true);
        }
    }

    public void advanceTurntableTimes(int type, int times) {
        doRecord(GDHistory.Event.TURNTABLE_DRAW_TIMES, type, times, true);
    }

    /**
     * 英雄升级次数
     */
    public void heroLevelUp() {
        doRecord(GDHistory.Event.HERO_LEVEL_UP_TIME, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 英雄升级总级数
     */
    public void heroLevelUpSum(int lv) {
        doRecord(GDHistory.Event.HERO_LEVEL_UP_SUM, GDHistory.TID_NULL, lv, true);
    }


    /**
     * 徽章合成
     */
    public void forgeTrainRune() {
        doRecord(GDHistory.Event.FORGE_TRAIN_RUNE, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 藏宝阁，杂货铺购买
     */
    public void mallBuyItem(int mallId, int num) {
        doRecord(GDHistory.Event.MALL_BUY_ITEM, GDHistory.TID_NULL, 1, true);
        mallBuy(mallId, num);
    }

    /**
     * 圣器升级
     */
    public void hallowLevelUp() {
        doRecord(GDHistory.Event.HALLOW_LEVEL_UP, GDHistory.TID_NULL, 1, true);
    }

    public void hallowRefineLevel(int level) {
        doRecord(GDHistory.Event.HALLOW_REFINE_LEVEL_UP, GDHistory.TID_NULL, level, false);
    }

    public void hallowTaskRewardTimes() {
        doRecord(GDHistory.Event.HALLOW_TASK_REWARD_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void hallowGradeUp(List<Hallow> hallows) {
        int[] levelNum = new int[GDHistory.HALLOWS_GRADE_OPT.length];
        for (Hallow hallow : hallows) {
            for (int i = 0; i < GDHistory.HALLOWS_GRADE_OPT.length; i++) {
                if (hallow.grade >= GDHistory.HALLOWS_GRADE_OPT[i]) {
                    levelNum[i]++;
                }
            }
        }
        for (int i = 0; i < GDHistory.HALLOWS_GRADE_OPT.length; i++) {
            doRecord(
                    GDHistory.Event.HALLOW_GRADE_UP,
                    GDHistory.HALLOWS_GRADE_OPT[i],
                    levelNum[i],
                    false);
        }
    }

    /**
     * 徽章重铸
     */
    public void runeRecast(long cost) {
        doRecord(GDHistory.Event.RUNE_RECAST, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.RUNE_RECAST_RANDOM_TIMES, GDHistory.TID_NULL, 1, true);
        if (cost > 0) {
            doRecord(GDHistory.Event.RUNE_RECAST_COST, GDHistory.TID_NULL, cost, true);
        }
    }

    public void runeRecastQuality(int quality) {
        if (quality >= GDProp.Quality.Q4) {
            doRecord(GDHistory.Event.RUNE_RECAST_QUALITY, quality, 1, true);
        }
    }

    /**
     * 水晶峡谷旅挑战成功
     */
    public void spiceFbChallenge() {
        doRecord(GDHistory.Event.SPICEFB_CHALLENGE, GDHistory.TID_NULL, 1, true);
    }

    public void spiceFbChallengeOrMop() {
        doRecord(GDHistory.Event.SPICEFB_CHALLENGE_MOP, GDHistory.TID_NULL, 1, true);
    }

    public void spiceFbStar(int star) {
        doRecord(GDHistory.Event.SPICEFB_STAR, GDHistory.TID_NULL, star, false);
    }

    public void spicesOnNum() {
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            int num = 0;
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.spicesOn != null && hero.spicesOn.spiceMap != null) {
                    num += hero.spicesOn.spiceMap.size();
                }
            }
            if (num > 0) {
                doRecord(GDHistory.Event.SPICE_ON_NUM, GDHistory.TID_NULL, num, false);
            }
        }
    }

    public void spiceFuseTimes(int tid) {
        doRecord(GDHistory.Event.SPICE_FUSE_TIMES, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.SPICE_FUSE_TID, tid, 1, true);
    }

    public void spiceCallGoodLuck() {
        doRecord(GDHistory.Event.SPICE_CALL_GOOD_LUCK, GDHistory.TID_NULL, 1, true);
    }

    public void mallBuy(int mallId, int num) {
        doRecord(GDHistory.Event.MALL_BUY_TIMES, mallId, num, true);
    }

    public void shareHero() {
        doRecord(GDHistory.Event.SHARE_HERO, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 累计签到
     */
    public void onSignUp() {
        doRecord(GDHistory.Event.ON_SIGN_UP, GDHistory.TID_NULL, 1, true);
    }

    public void heroLevelNumTotal(int level) {
        int interval = 0;
        for (int i : GDHistory.HERO_LEVEL_NUM_OPT) {
            if (level >= i) {
                interval = i;
            } else {
                break;
            }
        }
        if (interval > 0) {
            doRecord(GDHistory.Event.HERO_LEVEL_NUM_TOTAL, interval, 1, true);
        }
    }

    /**
     * 当前拥有X等级英雄的个数
     */
    public void heroLevelNumUpdate() {
        int[] levelNum = new int[GDHistory.HERO_LEVEL_NUM_OPT.length];
        for (Hero hero : this.parent.getRole().getBag().hero.getList()) {
            for (int i = 0; i < GDHistory.HERO_LEVEL_NUM_OPT.length; i++) {
                if (hero.level >= GDHistory.HERO_LEVEL_NUM_OPT[i]) {
                    levelNum[i]++;
                }
            }
        }
        for (int i = 0; i < GDHistory.HERO_LEVEL_NUM_OPT.length; i++) {
            doRecord(
                    GDHistory.Event.HERO_NOW_LEVEL_NUM,
                    GDHistory.HERO_LEVEL_NUM_OPT[i],
                    levelNum[i],
                    false);
        }
    }

    /**
     * 食灵收集([累计]获得指定星级食灵的个数)
     */
    public void heroCollection(int star) {
        doRecord(GDHistory.Event.HEROS_COLLECTION, star, 1, true);

//        // 累积收集大于等于指定星级的英雄的个数
//        for (int i = 0; i < GDHistory.HERO_STAR_NUM_OPT.length; i++) {
//            int starCfg = GDHistory.HERO_STAR_NUM_OPT[i];
//            if (star >= starCfg) {
//                doRecord(GDHistory.Event.HEROS_COLLECTION, starCfg, 1, true);
//            }
//        }
    }

    public void heroDifferentStarCollection() {
        doRecord(GDHistory.Event.DIFFERENT_HEROS_COLLECTION, 5, 1, true);
    }

    public void heroGradeUp(int grade) {
        doRecord(GDHistory.Event.HEROS_ANY_GRADE_UP, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.HEROS_GRADE_UP, grade, 1, true);
    }

    /**
     * 好友个数
     */
    public void friendNum(int num) {
        doRecord(GDHistory.Event.FRIEND_NUM, GDHistory.TID_NULL, num, false);
    }


    /**
     * 领取月卡
     *
     * @param tid 月卡模板id
     */
    public void MonthCardGet(int tid) {
        if (GDHistory.TRADE_MALL_NORMAL_MONTH_CARD_TID == tid) {
            doRecord(GDHistory.Event.MONTH_NORMAL_CARD_GET, GDHistory.TID_NULL, 1, true);
            return;
        }
        if (GDHistory.TRADE_MALL_ADVANCE_MONTH_CARD_TID == tid) {
            doRecord(GDHistory.Event.MONTH_ADVANCED_CARD_GET, GDHistory.TID_NULL, 1, true);
            return;
        }
    }

    public void equipCompose(int quality, int num) {
        doRecord(GDHistory.Event.EQUIP_COMPOSE, quality, num, true);
    }

    public void equipComposeStar(int star, int num) {
        doRecord(GDHistory.Event.EQUIP_COMPOSE_STAR, star, num, true);
    }

    public void drawUpPoolFairy(int times) {
        doRecord(GDHistory.Event.DRAW_UP_POOL_FAIRY, GDHistory.TID_NULL, times, true);
    }

    public void drawGoldEgg(int times) {
        doRecord(GDHistory.Event.DRAW_GOLD_EGG, GDHistory.TID_NULL, times, true);
    }

    public void challengeLostDreamLand() {
        doRecord(GDHistory.Event.CHALLENGE_LOST_DREAM_LAND, GDHistory.TID_NULL, 1, true);
    }

    public void drawLottery(int times) {
        doRecord(GDHistory.Event.DRAW_LOTTERY, GDHistory.TID_NULL, times, true);
    }

    public void godEquipBreakUp(int star) {
        doRecord(GDHistory.Event.GOD_EQUIP_BREAK_UP, star, 1, true);
    }

    public void bossTrainTimes() {
        doRecord(GDHistory.Event.BOSS_TRAIN_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void bossTrainDamage(long damage) {
        doRecord(GDHistory.Event.BOSS_TRAIN_DAMAGE, GDHistory.TID_NULL, damage, false);
    }

    public void moonFightChallengeTimes(int times) {
        doRecord(GDHistory.Event.MOON_FIGHT_CHALLENGE_TIMES, GDHistory.TID_NULL, times, false);
    }

    public void moonFightWinTimes(int level, int times) {
        doRecord(GDHistory.Event.MOON_FIGHT_WIN_TIMES, level, times, false);
    }

    public void equipComposeTimes() {
        doRecord(GDHistory.Event.EQUIP_COMPOSE_TIMES, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 装备增加
     */
    public void equipAdded(int quality, int num) {
        doRecord(GDHistory.Event.EQUIP_NUM_QUALITY_ADD, quality, num, true);
        doRecord(GDHistory.Event.EQUIP_NUM_ADD, GDHistory.TID_NULL, num, true);
    }

    /**
     * 装备强化
     */
    public void equipUpgrade() {
        doRecord(GDHistory.Event.EQUIP_UPGRADE, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.EQUIP_LEVEL_UP_RANDOM_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void equipsQualityOnHero(Hero hero) {
        Map<Byte, Integer> qualityNums = new HashMap<>();
        for (Equip equip : hero.equipsOn.getPosItems().values()) {
            byte quality = equip.getTpl(this.parent.getRole().toPlayBuildContext()).quality;
            qualityNums.put(quality, qualityNums.getOrDefault(quality, 0) + 1);
        }
        for (Map.Entry<Byte, Integer> entry : qualityNums.entrySet()) {
            doRecord(GDHistory.Event.EQUIPS_QUALITY_ON_HERO, entry.getKey(), entry.getValue(), false);
        }
    }

    /**
     * 获取积分赛最高累计
     */
    public void addPointRacePoints(Long point) {
        doRecord(GDHistory.Event.POINT_RACE_POINT, GDHistory.TID_NULL, point, false);
    }

    /**
     * 积分赛历史最高排名
     */
    public void addPointRaceRank(int rank) {
        doRecord(GDHistory.Event.POINT_RACE_RANK, GDHistory.TID_NULL, rank, false);
    }

    /**
     * 加入或者创建协会
     */
    public void hadAGuild() {
        doRecord(GDHistory.Event.GUILD_CREATE_ENTER, GDHistory.TID_NULL, 1, false);
    }

    /**
     * 击杀协会boss
     */
    public void killGuildBoss() {
        doRecord(GDHistory.Event.KILL_GUILD_BOSS, GDHistory.TID_NULL, 1, true);
    }


    public void passForbidden() {
        doRecord(GDHistory.Event.PASS_FORBIDDEN, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 登陆
     */
    public void login() {
        doRecord(GDHistory.Event.LOGIN_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void worldtreeLevel(int level) {
        doRecord(GDHistory.Event.WORLD_TREE_LEVEL, GDHistory.TID_NULL, level, false);
    }

    public void worldTreeBoxNum() {
        doRecord(GDHistory.Event.WORLD_TREE_BOX_NUM, GDHistory.TID_NULL, 1, true);
    }

    public void worldTreeAdditionLevel(int level) {
        doRecord(GDHistory.Event.WORLD_TREE_ADDITION_LEVEL, GDHistory.TID_NULL, level, false);
    }

    public void worldBossDamage(long damage) {
        doRecord(GDHistory.Event.WORLD_BOSS_DAMAGE, GDHistory.TID_NULL, damage, false);
    }

    /**
     * 世界BOSS鼓舞
     */
    public void worldBossBuff() {
        doRecord(GDHistory.Event.WORLD_BOSS_BUFF, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 世界BOSS挑战
     */
    public void worldBossChallenge() {
        doRecord(GDHistory.Event.WORLD_BOSS_CHALLENGE, GDHistory.TID_NULL, 1, true);
    }

    public void manorLevelUp(int level) {
        doRecord(GDHistory.Event.MANOR_LEVEL_UP, GDHistory.TID_NULL, level, false);
    }

    public void manorGotHangReward() {
        doRecord(GDHistory.Event.MANOR_GOT_HANG_REWARD, GDHistory.TID_NULL, 1, true);
    }

    public void createGuild() {
        doRecord(GDHistory.Event.CREATE_GUILD, GDHistory.TID_NULL, 1, false);
    }

    public void hallowNum(int size) {
        doRecord(GDHistory.Event.UNLOCKED_HALLOW_NUM, GDHistory.TID_NULL, size, false);
    }

    /**
     * 激活圣器技能
     *
     * @param num
     */
    public void hallowSkillNum(int num) {
        doRecord(GDHistory.Event.UNLOCKED_HALLOW_SKILL_NUM, GDHistory.TID_NULL, num, false);
    }

    public void haloNum(int size) {
        doRecord(GDHistory.Event.UNLOCKED_HALO_NUM, GDHistory.TID_NULL, size, false);
    }

    /**
     * 无论是挑战还是扫荡
     */
    public void mainTowenWinTimes() {
        doRecord(GDHistory.Event.TOWER_WIN_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void mainTowerPass(int floor) {
        mainTowenWinTimes();
        doRecord(GDHistory.Event.MAIN_TOWER, GDHistory.TID_NULL, floor, false);
    }

    public void partTowerFail() {
        doRecord(GDHistory.Event.PART_TOWER_FAIL, GDHistory.TID_NULL, 1, true);
    }

    public void partTowerPassFloor(int floor) {
        mainTowenWinTimes();
        doRecord(GDHistory.Event.PART_TOWER_PASS_FLOOR, GDHistory.TID_NULL, floor, false);
    }

    public void passIsland() {
        doRecord(GDHistory.Event.PASS_ISLAND, GDHistory.TID_NULL, 1, true);
    }

    public void passIslandDifficulty(int difficulty) {
        doRecord(GDHistory.Event.PASS_ISLAND_DIFFICULTY, difficulty, 1, true);
    }

    public void killDifficultyIslandBoss(int difficulty) {
        doRecord(GDHistory.Event.ISLAND_WIN_DIFFICULTY_BOSS_TIMES, difficulty, 1, true);
    }

    public void islandWinBossTimes() {
        doRecord(GDHistory.Event.ISLAND_WIN_BOSS_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void islandWin() {
        doRecord(GDHistory.Event.ISLAND_WIN_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void killGhost(ExorcismGhostRow row) {
        doRecord(GDHistory.Event.KILL_GHOST, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.KILL_GHOST_QUALITY, row.quality, 1, true);
        doRecord(GDHistory.Event.KILL_GHOST_PROTO, row.protoId, 1, true);
    }

    public void killGhostPoint(int point) {
        doRecord(GDHistory.Event.KILL_GHOST_POINT, GDHistory.TID_NULL, point, true);
    }

    public void refreshGhost() {
        doRecord(GDHistory.Event.REFRESH_GHOST, GDHistory.TID_NULL, 1, true);
    }

    public void backLogin() {
        doRecord(GDHistory.Event.BACK_LOGIN, GDHistory.TID_NULL, 1, false);
    }

    public void funcPositionUpdate() {
        doRecord(GDHistory.Event.FUNC_POSITION_UPDATE, GDHistory.TID_NULL, 1, true);
    }

    public void heroEquipOn(int value) {
        doRecord(GDHistory.Event.HERO_EQUIP_ON, GDHistory.TID_NULL, value, true);
    }

    public void compositeHero() {
        doRecord(GDHistory.Event.FRAGMENT_COMPOSITE_HERO, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 新功能开启
     *
     * @param funcId 功能id
     */
    public void newFuncOpen(int funcId) {
        doRecord(GDHistory.Event.NEW_FUNC_OPEN, funcId, 1, true);
    }

    /**
     * 激活圣器
     */
    public void unlockHallow() {
        doRecord(GDHistory.Event.UNLOCK_HALLOW, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 领取成就任务奖励
     */
    public void receiveAchievementReward() {
        doRecord(GDHistory.Event.GET_ACHIEVEMENT_REWARD, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 领取VIP奖励
     */
    public void receiveVipReward() {
        doRecord(GDHistory.Event.GET_VIP_REWARD, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 发送世界消息
     */
    public void sendWorldMsg() {
        doRecord(GDHistory.Event.SEND_WORLD_MESSAGE, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 挑战缚灵之塔(不论成败)
     */
    public void challengeMainTower() {
        doRecord(GDHistory.Event.CHALLENGE_MAIN_TOWER, GDHistory.TID_NULL, 1, true);
    }

    public void challengeDailyFb(int type, int times) {
        doRecord(GDHistory.Event.CHALLENGE_DAILY_FB, type, times, true);
    }

    /**
     * 庄园任命管家
     */
    public void manorAppointment() {
        doRecord(GDHistory.Event.MANOR_APPOINTMENT, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 穿戴徽章
     */
    public void runeOn() {
        doRecord(GDHistory.Event.RUNE_ON, GDHistory.TID_NULL, 1, true);
    }

    public void runeForgeQuality(Rune rune) {
        doRecord(GDHistory.Event.RUNE_FORGE_QUALITY, rune.getTpl(this.parent.getRole().toPlayBuildContext()).quality, 1, true);
    }

    /**
     * 香料穿戴
     */
    public void spiceOn() {
        doRecord(GDHistory.Event.SPICE_ON, GDHistory.TID_NULL, 1, true);
    }

    public void spiceCall(int times) {
        doRecord(GDHistory.Event.SPICE_CALL_TIMES, GDHistory.TID_NULL, times, true);
    }

    public void spiceGetQuality(int quality, long num) {
        doRecord(GDHistory.Event.SPICE_GET_QUALITY, quality, num, true);
    }

    public void spiceUpgrade() {
        doRecord(GDHistory.Event.SPICE_UPGRADE, GDHistory.TID_NULL, 1, true);
    }

    public void spiceGet(int num) {
        doRecord(GDHistory.Event.SPICE_GET, GDHistory.TID_NULL, num, true);
    }

    public void spiceGetLevel(int level, int quality) {
        doRecord(GDHistory.Event.SPICE_GET_LEVEL, level, 1, true);
        if (quality >= GDProp.Quality.Q4) {
            doRecord(GDHistory.Event.SPICE_LEVEL_UP_TO_7, GDHistory.TID_NULL, 1, true);
        }
    }

    public void teamHeroStar() {
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            int star = 0;
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                star += Math.min(hero.getTpl(parent.getRole().getGame()).star, 14);
            }
            if (star > 0) {
                doRecord(GDHistory.Event.TEAM_HERO_STAR, GDHistory.TID_NULL, star, false);
            }
        }
    }

    public void inscriptionUpgrade() {
        doRecord(GDHistory.Event.INSCRIPTION_UPGRADE, GDHistory.TID_NULL, 1, true);
    }

    public void inscriptionOn() {
        doRecord(GDHistory.Event.INSCRIPTION_ON, GDHistory.TID_NULL, 1, true);
    }

    public void inscriptionPageOn() {
        doRecord(GDHistory.Event.INSCRIPTION_PAGE_ON, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 最高战力变更
     */
    public void fightPowerUp(long power) {
        doRecord(GDHistory.Event.FIGHT_POWER, GDHistory.TID_NULL, power, false);
    }

    /**
     * 完成每日任务
     */
    public void taskDailyDone() {
        doRecord(GDHistory.Event.TASK_DAILY_DONE, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 购买礼包补给
     *
     * @param num 购买数量
     */
    public void treasureSupplyBuy(int num) {
        doRecord(GDHistory.Event.TREASURE_SUPPLY_BUY, GDHistory.TID_NULL, num, true);
    }

    /**
     * 协会宝库消费
     *
     * @param num 消费数量
     */
    public void guildMallBuy(int num) {
        doRecord(GDHistory.Event.GUILD_MALL_BUY, GDHistory.TID_NULL, num, true);
    }

    /**
     * 藏宝阁刷新
     */
    public void treasureMallRefresh() {
        doRecord(GDHistory.Event.TREASURE_MALL_REFRESH, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 天赋商店刷新
     */
    public void talentMallRefresh() {
        doRecord(GDHistory.Event.TALENT_MALL_REFRESH, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 协会BOSS鼓舞
     */
    public void guildBossBuff() {
        doRecord(GDHistory.Event.GUILD_BOSS_BUFF, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 英雄升星
     *
     * @param hero    英雄实例
     * @param newStar 新星级
     */
    public void heroStarUp(Hero hero, int newStar) {
        doRecord(GDHistory.Event.HERO_STAR_UP_TIME, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.HERO_STAR_UP_TO_LEVEL_TIME, newStar, 1, true);
    }

    /**
     * 接取情报任务
     *
     * @param quality 情报任务品质
     */
    public void informationTaskGet(int quality) {
        doRecord(GDHistory.Event.INFORMATION_TASK, GDHistory.TID_NULL, 1, true);
        doRecord(GDHistory.Event.INFORMATION_TASK_QUALITY, quality, 1, true);
    }

    public void refreshInformationTask() {
        doRecord(GDHistory.Event.REFRESH_INFORMATION_TASK, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 回放录像
     */
    public void playVideo() {
        doRecord(GDHistory.Event.PLAY_VIDEO, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 布阵设置
     *
     * @param num 布阵设置数
     */
    public void positionSet(int num) {
        doRecord(GDHistory.Event.POSITION_SET_NUM, GDHistory.TID_NULL, num, false);
    }

    /**
     * 打开过vip特权商店
     *
     * @param type
     */
    public void openPage(int type) {
        //参数:1:特权商城
        doRecord(GDHistory.Event.OPEN_PAGE, type, 1, false);
    }

    /**
     * 领取主线挂机奖励
     */
    public void gotAdventureHangReward() {
        doRecord(GDHistory.Event.ADVENTURE_HANG_REWARD, GDHistory.TID_NULL, 1, true);
    }

    public void taskDone(int taskId) {
        doRecord(GDHistory.Event.TASK_DONE, taskId, 1, true);
    }

    /**
     * 装备圣器
     */
    public void onHallow() {
        doRecord(GDHistory.Event.HALLOW_ON, GDHistory.TID_NULL, 1, true);
    }

    public void goldComeOn() {
        doRecord(GDHistory.Event.GOLD_COMEON, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 神魔共生
     */
    public void upPoolStrongCall(int times) {
        doRecord(GDHistory.Event.UP_POOL_STRONG_HERO, GDHistory.TID_NULL, times, true);
    }

    /**
     * 精英召唤获得xx个up英雄
     */
    public void upPoolUpTimes() {
        doRecord(GDHistory.Event.UP_POOL_UP_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void battleRoyaleFail(int tid) {
        doRecord(GDHistory.Event.BATTLE_ROYALE_FAIL, tid, 1, true);
    }

    public void battleRoyalePassed() {
        doRecord(GDHistory.Event.BATTLE_ROYALE_PASSED, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 某食灵升级至几星
     */
    public void restrictHeroStarUpTo(int tid, int num) {
        doRecord(GDHistory.Event.RESTRICT_HERO_STAR_UP_TO, tid, num, false);
    }

    /**
     * 英雄星级总和
     */
    public void heroStarTotal(long starTotal) {
        doRecord(GDHistory.Event.HERO_STAR_TOTAL, GDHistory.TID_NULL, starTotal, false);
    }

    /**
     * 装备评分总和
     */
    public void equipPointTotal(long equipPointTotal) {
        doRecord(GDHistory.Event.EQUIP_POINT_TOTAL, GDHistory.TID_NULL, equipPointTotal, false);
    }

    /**
     * 徽章突破
     */
    public void runeBreakToForever() {
        doRecord(GDHistory.Event.RUNE_BREAK_TO_FOREVER, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 职业英雄收集
     */
    public void heroOccupationCollection(Role role, int occupation, int star) {
        for (byte job : GDHero.Job.ALL) {
            OptionalInt starOption = role.getBag().hero.getList().stream()
                    .filter(hero -> hero.getTpl(role.toPlayBuildContext()).job == job)
                    .mapToInt(hero -> hero.getTpl(role.toPlayBuildContext()).star)
                    .max();
            if (starOption.isPresent()) {
                doRecord(GDHistory.Event.HERO_OCCUPATION_COLLECTION, job, starOption.getAsInt(), false);
            }
        }
//        doRecord(GDHistory.Event.HERO_OCCUPATION_COLLECTION, occupation, star, false);
    }

    public void furnitureCallItemConsume(long num) {
        doRecord(GDHistory.Event.FURNITURE_CALL_ITEM_CONSUME, GDHistory.TID_NULL, num, true);
    }

    /**
     * 参加协会战一次
     */
    public void guildRaceOneTime() {
        doRecord(GDHistory.Event.GUILD_RACE_ONE_TIME, GDHistory.TID_NULL, 1, false);
    }

    /**
     * 装备转换几次
     */
    public void equipTransfer() {
        doRecord(GDHistory.Event.EQUIP_TRANSFER, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 商店刷新次数
     *
     * @param shopId
     */
    public void mallRefreshTime(int shopId) {
        doRecord(GDHistory.Event.MALL_REFRESH_TIME, shopId, 1, true);
    }

    /**
     * 族徽升级一次
     */
    public void RaceBadgeLevelUpTime() {
        doRecord(GDHistory.Event.RACE_BADGE_LEVEL_UP_TIME, GDHistory.TID_NULL, 1, true);
    }

    public void raceBadgeCampLevel(int camp, int level) {
        doRecord(GDHistory.Event.RACE_BADGE_CAMP_LEVEL, camp, level, false);
    }

    public void raceBadgeCampGrade(int camp, int grade) {
        doRecord(GDHistory.Event.RACE_BADGE_CAMP_GRADE, camp, grade, false);
    }

    /**
     * 手办定制次数
     *
     * @param rcount
     */
    public void furnitureCallTime(int rcount) {
        doRecord(GDHistory.Event.FURNITURE_CALL_TIME, GDHistory.TID_NULL, rcount, true);
    }

    /**
     * 手办穿戴了几次
     */
    public void furnitureOnTime() {
        doRecord(GDHistory.Event.FURNITURE_ON_TIME, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 命运之扉通关最高几关
     *
     * @param levelId
     */
    public void heroInstanceSingleLevelPass(int levelId) {
        doRecord(GDHistory.Event.HERO_INSTANCE_SINGLE_LEVEL_PASS, GDHistory.TID_NULL, levelId, false);
    }


    /**
     * 命运之扉扫荡次数
     */
    public void heroInstanceUpdateWipeTime() {
        doRecord(GDHistory.Event.HERO_INSTANCE_UPDATE_WIPE_TIME, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 灵能矿场通关多少关
     *
     * @param passedFloor
     */
    public void minecraftPass(int passedFloor) {
        doRecord(GDHistory.Event.MINECRAFT_PASS, GDHistory.TID_NULL, passedFloor, false);
    }

    /**
     * 灵能矿场占领一次矿洞
     */
    public void minecraftWin() {
        doRecord(GDHistory.Event.MINECRAFT_WIN, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 灵能矿场领取挂机奖励几次
     */
    public void minecraftHangReward() {
        doRecord(GDHistory.Event.MINECRAFT_HANG_REWARD, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 灵能矿场合成领取几次
     */
    public void minecraftCompoundReward() {
        doRecord(GDHistory.Event.MINECRAFT_COMPOUND_REWARD, GDHistory.TID_NULL, 1, true);
    }

    public void minecraftLevelUp(int level) {
        doRecord(GDHistory.Event.MINECRAFT_LEVEL_UP, GDHistory.TID_NULL, level, false);
    }

    public void minecraftRobOther() {
        doRecord(GDHistory.Event.MINECRAFT_ROB_OTHER, GDHistory.TID_NULL, 1, true);
    }

    /**
     * 物品合成功能【】道具【】次
     *
     * @param item
     */
    public void itemComposeTargetNum(MixResItem item) {
        if (item == null) {
            return;
        }
        doRecord(GDHistory.Event.ITEM_COMPOSE_TARGET_TIME, item.tid, item.num, true);
    }

    /**
     * 领主讨伐发起一次挑战
     */
    public void challengeCrossBoss() {
        doRecord(GDHistory.Event.CROSS_BOSS_CHALLENGE, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 购买商城商品
     *
     * @param id  物品在商城表中的id
     * @param num
     */
    public void itemBuy(int id, int num) {
        doRecord(GDHistory.Event.ITEM_BUY, id, num, true);
    }

    public void naturalCallHeroBuy(int job, long num) {
        doRecord(GDHistory.Event.NATURAL_CALL_HERO_BUY, job, num, true);
    }

    /**
     * 穿戴宝石次数
     */
    public void gemOnTime() {
        doRecord(GDHistory.Event.GEM_ON_TIME, GDHistory.TID_NULL, 1, true);
    }


    /**
     * 宝石升级次数
     */
    public void gemLevelUpTime() {
        doRecord(GDHistory.Event.GEM_LEVEL_UP_TIME, GDHistory.TID_NULL, 1, true);
    }

    public void gemLevelNum() {
        Map<Integer, Integer> levelNumMap = new HashMap<>();
        Map<Integer, Integer> godLevelNumMap = new HashMap<>();
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        int totalLevel = 0;
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.equipsOn != null && !hero.equipsOn.equipMap.isEmpty()) {
                    for (Equip equip : hero.equipsOn.equipMap.values()) {
                        if (equip.hasGem()) {
                            for (Gem gem : equip.getGemsOn().getPosItems().values()) {
                                int level = gem.getTpl(parent.getRole().getGame()).level;
                                boolean isGod = gem.getTpl(parent.getRole().getGame()).isGradeGem;
                                for (int i = 1; i <= level; ++i) {
                                    levelNumMap.put(i, levelNumMap.getOrDefault(i, 0) + 1);
                                    if (isGod) {
                                        godLevelNumMap.put(i, godLevelNumMap.getOrDefault(i, 0) + 1);
                                    }
                                }
                                totalLevel += level;
                            }
                        }
                    }
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : levelNumMap.entrySet()) {
            doRecord(GDHistory.Event.GEM_LEVEL_NUM, entry.getKey(), entry.getValue(), false);
        }
        for (Map.Entry<Integer, Integer> entry : godLevelNumMap.entrySet()) {
            doRecord(GDHistory.Event.GEM_GOD_LEVEL_NUM, entry.getKey(), entry.getValue(), false);
        }
        if (totalLevel > 0) {
            doRecord(GDHistory.Event.TEAM_GEM_LEVEL, GDHistory.TID_NULL, totalLevel, false);
        }
    }

    public void equipQualityStarOn() {
        Map<Integer, Integer> qualityNumMap = new HashMap<>();
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.equipsOn != null && !hero.equipsOn.equipMap.isEmpty()) {
                    for (Equip equip : hero.equipsOn.equipMap.values()) {
                        EquipBaseRow equipBaseRow = equip.getTpl(parent.getRole().getGame());
                        if (equipBaseRow != null && equipBaseRow.quality >= GDProp.Quality.Q5) {
                            int star = equipBaseRow.quality == GDProp.Quality.Q5 ? equipBaseRow.star : 9;
                            for (int i = 1; i <= star; ++i) {
                                qualityNumMap.put(i, qualityNumMap.getOrDefault(i, 0) + 1);
                            }
                        }
                    }
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : qualityNumMap.entrySet()) {
            doRecord(GDHistory.Event.EQUIP_QUALITY_STAR_ON, entry.getKey(), entry.getValue(), false);
        }
    }

    public void furnitureQualityOn() {
        Map<Integer, Integer> qualityNumMap = new HashMap<>();
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.furnituresOn != null && !hero.furnituresOn.furnitureMap.isEmpty()) {
                    for (Furniture furniture : hero.furnituresOn.furnitureMap.values()) {
                        FurnitureItemBaseRow furnitureBaseRow = furniture.getTpl(parent.getRole().getGame());
                        if (furnitureBaseRow != null) {
                            for (int i = 1; i <= furnitureBaseRow.quality; ++i) {
                                qualityNumMap.put(i, qualityNumMap.getOrDefault(i, 0) + 1);
                            }
                        }
                    }
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : qualityNumMap.entrySet()) {
            doRecord(GDHistory.Event.TEAM_FURNITURE_QUALITY, entry.getKey(), entry.getValue(), false);
        }
    }

    public void teamYokeOn() {
        Map<Integer, Integer> starNumMap = new HashMap<>();
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.yokeOn != null && !hero.yokeOn.heroUidMap.isEmpty()) {
                    for (String heroUid : hero.yokeOn.heroUidMap.values()) {
                        Hero yokeHero = parent.getRole().getBag().hero.getItem(heroUid);
                        if (yokeHero != null) {
                            for (int i = 5; i <= yokeHero.getTpl(parent.getRole().getGame()).star; ++i) {
                                starNumMap.put(i, starNumMap.getOrDefault(i, 0) + 1);
                            }
                        }
                    }
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : starNumMap.entrySet()) {
            doRecord(GDHistory.Event.TEAM_YOKE_HERO_STAR, entry.getKey(), entry.getValue(), false);
        }
    }

    public void teamRuneOn() {
        Map<Integer, Integer> qualityNumMap = new HashMap<>();
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.runesOn != null && !hero.runesOn.runeMap.isEmpty()) {
                    for (Rune rune : hero.runesOn.runeMap.values()) {
                        RuneBaseRow runeBase = rune.getTpl(parent.getRole().getGame());
                        if (runeBase != null) {
                            for (int i = 1; i <= runeBase.quality; ++i) {
                                qualityNumMap.put(i, qualityNumMap.getOrDefault(i, 0) + 1);
                            }
                        }
                    }
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : qualityNumMap.entrySet()) {
            doRecord(GDHistory.Event.TEAM_RUNE_QUALITY, entry.getKey(), entry.getValue(), false);
        }
    }

    public void gemCompositeTimes() {
        doRecord(GDHistory.Event.GEM_COMPOSE, GDHistory.TID_NULL, 1, true);
    }

    public void gemSystemOpen() {
        doRecord(GDHistory.Event.GEM_SYSTEM_OPEN, GDHistory.TID_NULL, 1, true);
    }

    public void talentLevelUp(int level) {
        doRecord(GDHistory.Event.TALENT_LEVEL_UP, level, 1, true);
    }

    public void talentLevelTimes() {
        doRecord(GDHistory.Event.TALENT_LEVEL_TIMES, GDHistory.TID_NULL, 1, true);
    }

    public void teamTalentLevel() {
        Position position = parent.getRole().getFight().getPosition(GDFunc.ADVENTURE);
        if (position != null) {
            Map<Integer, Integer> levelNumMap = new HashMap<>();
            int level = 0;
            for (HeroGrid grid : position.grids) {
                Hero hero = parent.getRole().getBag().hero.getItem(grid.uid);
                if (hero != null && hero.newTalentOn != null && hero.newTalentOn.list != null) {
                    for (TalentItem item : hero.newTalentOn.list) {
                        HeroTalentRow row = item.getTpl(parent.getRole().toPlayBuildContext());
                        if (row != null) {
                            level += row.level;
                            for (int i = 1; i <= row.level; ++i) {
                                levelNumMap.put(i, levelNumMap.getOrDefault(i, 0) + 1);
                            }
                        }
                    }
                }
            }
            doRecord(GDHistory.Event.TEAM_TALENT_LEVEL, GDHistory.TID_NULL, level, false);
            for (Map.Entry<Integer, Integer> entry : levelNumMap.entrySet()) {
                doRecord(GDHistory.Event.TEAM_TALENT_LEVEL_NUM, entry.getKey(), entry.getValue(), false);
            }
        }
    }

    public void crystallDrawTimes(int times) {
        doRecord(GDHistory.Event.CRYSTALL_DRAW_TIMES, GDHistory.TID_NULL, times, true);
    }

    public void godEquipDrawTimes(int times) {
        doRecord(GDHistory.Event.GOD_EQUIP_DRAW, GDHistory.TID_NULL, times, true);
    }

    public void godEquipQuality(int quality) {
        doRecord(GDHistory.Event.GOD_EQUIP_DRAW_UP, quality, 1, true);
    }

    public void newHeroCallTimes(int times) {
        doRecord(GDHistory.Event.NEW_HERO_CALL, GDHistory.TID_NULL, times, true);
    }

    public void campHeroStarUp(int camp, int star) {
        doRecord(GDHistory.Event.CAMP_HERO_STAR_UP, camp, star, false);
    }

    private void doRecord(int event, int param, long value, boolean add) {
        try {
            if (this.parent == null) {
                logger.error("历史行为记录: this.parent == null, event={}", event);
                return;
            }
            if (this.parent.getRole() == null) {
                logger.error("历史行为记录: this.parent.master == null, event={}", event);
                return;
            }
            this.parent.record(event, param, value, add);
            this.parent.getRole().getTask().record(event, param, value, add);
            //福利红包条件记录
            this.parent.getRole().getRes().guild.envelope.doRecord(event, param, value, add);
            this.parent.getRole().getGame().activityGlobal.getEnableHandlerList(SingleCrossRankActivityHandler.class)
                    .forEach(e -> e.doRecord(this.parent.getRole(), event, param, value, add));
            this.parent.getRole().getGame().activityGlobal.getEnableHandlerList(SingleRankActivityHandler.class)
                    .forEach(e -> e.doRecord(this.parent.getRole(), event, param, value, add));
            this.parent.getRole().getActivity().doRecord(event, param, value);
            this.parent.getRole().getPay().gift.doRecord(event, param, value, add);
        } catch (Exception e) {
            logger.error("历史行为记录异常", e);
        }
    }
}
